package com.wgo.bpot.common.transport.util;

import java.net.MalformedURLException;
import java.net.URL;

import com.caucho.hessian.client.HessianProxyFactory;
import com.wgo.bpot.common.transport.exception.db.DatabaseException;
import com.wgo.bpot.common.transport.servicefacade.DomainServerService;
import com.wgo.bpot.common.transport.servicefacade.LightServices;
import com.wgo.bpot.common.transport.servicefacade.ServiceFactory;
import com.wgo.bpot.common.transport.servicefacade.hessian.EnumSerializerFactory;
import com.wgo.bpot.common.transport.servicefacade.hessian.MethodSerializerFactory;
import com.wgo.bpot.common.transport.servicefacade.hessian.TransientTypeSerializerFactory;
import com.wgo.bpot.common.transport.servicefacade.hessian.UrlSerializerFactory;
/**
 * Used to create proxy of the remote service.
 * 
 * @author Petter L. H. Eide
 * TODO  This class should be moved into a separate module 
 */
public class HessianServiceFactory implements ServiceFactory {
	
	public <S> S createService(URL remoteUrl, Class<S> api) {
		return create(api,remoteUrl);
	}

	public LightServices createService(URL remoteUrl) {
		return create(LightServices.class,remoteUrl);
	}

	public DomainServerService createDomainServerService(URL remoteUrl) {
		return create(DomainServerService.class,remoteUrl);
	}
	
	private <S> S create(Class<S> clazz, URL remoteUrl) {
		Assert.<URL>assertNotNull(remoteUrl);
		S service = null;
		HessianProxyFactory hessianFactory = new HessianProxyFactory();
		hessianFactory.getSerializerFactory().addFactory(new EnumSerializerFactory());
		hessianFactory.getSerializerFactory().addFactory(new MethodSerializerFactory());
		hessianFactory.getSerializerFactory().addFactory(new TransientTypeSerializerFactory());
		hessianFactory.getSerializerFactory().addFactory(new UrlSerializerFactory());
//		hessianFactory.getSerializerFactory().addFactory(new FloatSerializerFactory()); //TODO: does not affect floats.. (is not triggered..)
		try {
			hessianFactory.getRemoteResolver();
		} catch (RuntimeException e1) {
			throw new DatabaseException("Could not connect to server, please check server adress.", e1);
		}
		try {
			service = (S)hessianFactory.create(clazz, remoteUrl.toExternalForm());
		} catch (MalformedURLException e) {
			throw new DatabaseException("Malformed URL", e);
		}
		return service;
	}

}
